package com.lyw.utils;

import com.lyw.constants.CommonConstants;
import com.lyw.exception.GlobalException;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;

public class ReflectUtil {
    public static final String[] SPECIAL_FIELDS = new String[]{"username"};

    private ReflectUtil() {}

    public static List<String> getClassFieldNames(Class<?> clazz) {

        if (clazz == null) {
            throw new GlobalException("获取当前 class 类的所有属性名称时，不能为空！");
        }

        Field[] fields = clazz.getDeclaredFields();

        if (fields.length == 0) {
            throw new GlobalException("当前[" + clazz.getName() + "]类没有任何属性！");
        }

        List<String> fieldNames = new CopyOnWriteArrayList<>();

        for (int i = 0; i < fields.length; i++) {
            if (fields[i].getName().endsWith(CommonConstants.IGNORE_FIELD_SUFFIX_BANE))
                continue;
            fieldNames.add(fields[i].getName());
        }

        return fieldNames;
    }

    public static Object setClassValueByFieldNames(List<String> fieldNames, Properties properties, Class<?> clazz) {

        if (clazz == null) {
            throw new GlobalException("获取当前 class 类的 Properties 配置信息是，不能为空！");
        }

        Constructor<?> constructor = null;
        try {
            constructor = clazz.getConstructor();
        } catch (NoSuchMethodException e) {
            throw new GlobalException("当前[" + clazz.getName() + "]类没有无参构造函数！");
        }

        Object o = null;
        try {
            o = constructor.newInstance();
        } catch (Exception e) {
            throw new GlobalException("获取当前properties配置信息时，无参构造函数调用失败！");
        }

        for (String fieldName : fieldNames) {

            String methodName = StringUtil.format("set{}{}", fieldName.substring(0, 1).toUpperCase(), fieldName.substring(1));
            String value = properties.getProperty(fieldName);

            if (value == null || "".equals(value)) {
                continue;
            }

            Class<?> typeClazz = null;
            Object val = null;
            if (SimpleFormatterUtil.INTEGER.matcher(value).find() && !StringUtil.isNotMatch(fieldName, SPECIAL_FIELDS)) {
                typeClazz = Long.class;
                val = Long.valueOf(value);
            } else if (SimpleFormatterUtil.BOOLEAN.matcher(value).find()) {
                typeClazz = Boolean.class;
                val = Boolean.valueOf(value);
            } else if (SimpleFormatterUtil.DOUBLE.matcher(value).find() || SimpleFormatterUtil.STRING.matcher(value).find() || SimpleFormatterUtil.STRING_NOT_EMPTY.matcher(value).find()) {
                typeClazz = String.class;
                val = value;
            } else if (SimpleFormatterUtil.CHAR.matcher(value).find()) {
                typeClazz = Character.class;
                val = value.charAt(0);
            } else {
                throw new GlobalException("当前 [ " + value + " ] 类型不支持，请联系管理员！");
            }

            Method method = null;
            try {
                method = clazz.getDeclaredMethod(methodName, typeClazz);
            } catch (NoSuchMethodException e) {
                throw new GlobalException(StringUtil.format("当前 [ {} ] 方法获取失败！", methodName));
            }

            try {
                method.invoke(o, val);
            } catch (Exception e) {
                throw new GlobalException(StringUtil.format("当前 [ {} ] 方法调用失败！", methodName));
            }
        }

        return o;
    }
}
